package hn.sigit.dao.hnd.administrative;

import hn.sigit.dao.ladm.administrative.LA_BAUnitDAO;
import hn.sigit.logic.geometry.GeometryOperations;
import hn.sigit.model.hnd.cadastre.HND_Parcel;
import hn.sigit.model.hnd.administrative.HND_Property;
import hn.sigit.model.ladm.administrative.LA_BAUnit;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.hibernatespatial.criterion.SpatialRestrictions;
import org.jboss.seam.Component;

import com.vividsolutions.jts.geom.MultiPolygon;

public class HND_PropertyDAO extends LA_BAUnitDAO {
	private static final long serialVersionUID = 1L;
	
	protected HND_PropertyDAO() {
		
	}
	

	public static List<HND_Property> loadProperties() {
		Session commonsDatabase = (Session)Component.getInstance(COMMONS_DB);
		return loadProperties(commonsDatabase);
	}
	public static HND_Property loadPropertyByID(long baUnitId) {
		Session commonsDatabase = (Session)Component.getInstance(COMMONS_DB);
		return loadPropertyByID(commonsDatabase, baUnitId);
	}
	public static Set<HND_Property> loadNeighborsByHNDProperty(HND_Property hndProperty) {
		return loadNeighborsByHNDProperty(getSession(), hndProperty);
	}
	

	@SuppressWarnings("unchecked")
	public static List<HND_Property> loadProperties(Session session) {
		Criteria criteria = session.createCriteria(HND_Property.class);
		
		return (List<HND_Property>)criteria.list();
	}
	
	public static HND_Property loadPropertyByID(Session session, long baUnitId) {
		Criteria criteria = session.createCriteria(HND_Property.class);
		criteria.add(Restrictions.eq("uID", baUnitId));
		
		return (HND_Property)criteria.uniqueResult();
	}
	
	public static Set<HND_Property> loadNeighborsByHNDProperty(Session session, HND_Property hndProperty) {
		MultiPolygon filter = GeometryOperations.getParcelsFromPropertyAsMultiPolygon(hndProperty);
		

		if (filter != null) {
			Set<HND_Property> hndPropertyList = new HashSet<HND_Property>();

			Criteria criteria = session.createCriteria(HND_Parcel.class);
			criteria.add(SpatialRestrictions.touches("shape", filter));
			
			@SuppressWarnings("unchecked")
			List<HND_Parcel> hndTouchingParcelList = (List<HND_Parcel>)criteria.list();
			if (hndTouchingParcelList != null) {
				for (HND_Parcel hndTouchingP : hndTouchingParcelList) {
					//TODO: Parameterize if we want touching parcels with intersection = 0
					/*
					if (hndTouchingP.getShape().intersection(filter).getLength() > 0.0001) {
						Set<LA_BAUnit> laBAUnitSet = hndTouchingP.getBaunits();
						if (laBAUnitSet != null) {
							for (LA_BAUnit laTouchingBAUnit : laBAUnitSet)
								if (laTouchingBAUnit instanceof HND_Property)
									hndPropertyList.add((HND_Property)laTouchingBAUnit);
						}
					}
					*/
					Set<LA_BAUnit> laBAUnitSet = hndTouchingP.getBaunits();
					if (laBAUnitSet != null) {
						for (LA_BAUnit laTouchingBAUnit : laBAUnitSet)
							if (laTouchingBAUnit instanceof HND_Property)
								hndPropertyList.add((HND_Property)laTouchingBAUnit);
					}
				}
			}
			return hndPropertyList;
		}
		
		return null;
	}
}
